home *** CD-ROM | disk | FTP | other *** search
/ Sprite 1984 - 1993 / Sprite 1984 - 1993.iso / src / cmds / nslookup / RCS / main.c,v < prev    next >
Encoding:
Text File  |  1988-11-27  |  25.0 KB  |  985 lines

  1. head     1.2;
  2. branch   ;
  3. access   ;
  4. symbols  ;
  5. locks    ; strict;
  6. comment  @ * @;
  7.  
  8.  
  9. 1.2
  10. date     88.11.27.13.47.54;  author douglis;  state Exp;
  11. branches ;
  12. next     1.1;
  13.  
  14. 1.1
  15. date     88.11.23.13.39.17;  author douglis;  state Exp;
  16. branches ;
  17. next     ;
  18.  
  19.  
  20. desc
  21. @original src from monet.
  22. @
  23.  
  24.  
  25. 1.2
  26. log
  27. @added declaration for undeclared var.
  28. @
  29. text
  30. @/*
  31.  * Copyright (c) 1985 Regents of the University of California.
  32.  * All rights reserved.
  33.  *
  34.  * Redistribution and use in source and binary forms are permitted
  35.  * provided that the above copyright notice and this paragraph are
  36.  * duplicated in all such forms and that any documentation,
  37.  * advertising materials, and other materials related to such
  38.  * distribution and use acknowledge that the software was developed
  39.  * by the University of California, Berkeley.  The name of the
  40.  * University may not be used to endorse or promote products derived
  41.  * from this software without specific prior written permission.
  42.  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
  43.  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
  44.  * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  45.  */
  46.  
  47. #ifndef lint
  48. char copyright[] =
  49. "@@(#) Copyright (c) 1985 Regents of the University of California.\n\
  50.  All rights reserved.\n";
  51. #endif /* not lint */
  52.  
  53. #ifndef lint
  54. static char sccsid[] = "@@(#)main.c    5.20 (Berkeley) 7/24/88";
  55. #endif /* not lint */
  56.  
  57. /*
  58.  *******************************************************************************
  59.  *  
  60.  *   main.c --
  61.  *  
  62.  *      Main routine and some action routines for the name server
  63.  *    lookup program.
  64.  *
  65.  *      Andrew Cherenson     
  66.  *    U.C. Berkeley Computer Science Div.
  67.  *    CS298-26, Fall 1985
  68.  *  
  69.  *******************************************************************************
  70.  */
  71.  
  72. #include <stdio.h>
  73. #include <strings.h>
  74. #include <sys/param.h>
  75. #include <netdb.h>
  76. #include <sys/socket.h>
  77. #include <netinet/in.h>
  78. #include <arpa/nameser.h>
  79. #include <resolv.h>
  80. #include <signal.h>
  81. #include <setjmp.h>
  82. #include <ctype.h>
  83. #include "res.h"
  84.  
  85. /*
  86.  *  Location of the help file.
  87.  */
  88.  
  89. #ifndef HELPFILE
  90. #define HELPFILE "/usr/local/nslookup.help"
  91. #endif
  92.  
  93.  
  94. /*
  95.  *  Default Internet address of the current host.
  96.  */
  97.  
  98. #if BSD < 43
  99. #define LOCALHOST "127.0.0.1"
  100. #endif
  101.  
  102.  
  103. /*
  104.  * Name of a top-level name server. Can be changed with 
  105.  * the "set root" command.
  106.  */
  107.  
  108. #ifndef ROOT_SERVER
  109. #define        ROOT_SERVER "sri-nic.arpa."
  110. #endif
  111. char         rootServerName[NAME_LEN];
  112.  
  113.  
  114. /*
  115.  *  Import the state information from the resolver library.
  116.  */
  117.  
  118. extern struct state _res;
  119.  
  120.  
  121. /*
  122.  *  Info about the most recently queried host.
  123.  */
  124.  
  125. HostInfo    curHostInfo;
  126. int        curHostValid = FALSE;
  127.  
  128.  
  129. /*
  130.  *  Info about the default name server.
  131.  */
  132.  
  133. HostInfo     *defaultPtr = NULL;
  134. char         defaultServer[NAME_LEN];
  135. struct in_addr    defaultAddr;
  136.  
  137.  
  138. /*
  139.  *  Initial name server query type is Address.
  140.  */
  141.  
  142. int         queryType = T_A;
  143. int         queryClass = C_IN;
  144.  
  145. /*
  146.  * Stuff for Interrupt (control-C) signal handler.
  147.  *  SockFD is the file descriptor for sockets used to
  148.  *  connect with the name servers. It has to be global to
  149.  *  allow the interrupt handler can close open sockets.
  150.  */
  151.  
  152. extern int     IntrHandler();
  153. int         sockFD = -1;
  154. FILE         *filePtr;
  155. jmp_buf     env;
  156.  
  157.  
  158.  
  159. /*
  160.  *******************************************************************************
  161.  *
  162.  *  main --
  163.  *
  164.  *    Initializes the resolver library and determines the address
  165.  *    of the initial name server. The yylex routine is used to
  166.  *    read and perform commands.
  167.  *
  168.  *******************************************************************************
  169.  */
  170.  
  171. main(argc, argv)
  172.     int        argc;
  173.     char    **argv;
  174. {
  175.     char    *wantedHost = NULL;
  176.     Boolean    useLocalServer;
  177.     int     result;
  178.     int        i;
  179.     struct hostent    *hp;
  180.     extern int    h_errno;
  181.  
  182.     /*
  183.      *  Initialize the resolver library routines.
  184.      */
  185.  
  186.     if (res_init() == -1) {
  187.     fprintf(stderr,"*** Can't initialize resolver.\n");
  188.     exit(1);
  189.     }
  190.  
  191.     /*
  192.      *  Allocate space for the default server's host info and
  193.      *  find the server's address and name. If the resolver library
  194.      *  already has some addresses for a potential name server,
  195.      *  then use them. Otherwise, see if the current host has a server.
  196.      *  Command line arguments may override the choice of initial server. 
  197.      */
  198.  
  199.     defaultPtr = (HostInfo *) Calloc(1, sizeof(HostInfo));
  200.  
  201.     /*
  202.      * Parse the arguments:
  203.      *  no args =  go into interactive mode, use default host as server
  204.      *    1 arg    =  use as host name to be looked up, default host will be server
  205.      *           non-interactive mode
  206.      *  2 args    =  1st arg: 
  207.      *             if it is '-', then 
  208.      *                ignore but go into interactive mode
  209.      *              else 
  210.      *                 use as host name to be looked up, 
  211.      *             go into non-interactive mode
  212.      *         2nd arg: name or inet address of server
  213.      *
  214.      *    "Set" options are specified with a leading - and must come before
  215.      *    any arguments. For example, to find the well-known services for
  216.      *  a host, type "nslookup -query=wks host"
  217.      */
  218.  
  219.     ++argv; --argc;        /* skip prog name */
  220.  
  221.     while (argc && *argv[0] == '-' && argv[0][1]) {
  222.     (void) SetOption (&(argv[0][1]));
  223.     ++argv; --argc;
  224.     }
  225.     if (argc > 2) {
  226.     Usage();
  227.     } 
  228.     if (argc && *argv[0] != '-') {
  229.     wantedHost = *argv;    /* name of host to be looked up */
  230.     }
  231.  
  232.     useLocalServer = FALSE;
  233.     if (argc == 2) {
  234.  
  235.     /*
  236.      *    Set explicit name server address.
  237.      */ 
  238.  
  239.     _res.nscount = 1;
  240.     _res.nsaddr.sin_addr.s_addr = inet_addr(*++argv);
  241.     if (_res.nsaddr.sin_addr.s_addr == (unsigned)-1) {
  242.         hp = gethostbyname(*argv);
  243.         if (hp == NULL){
  244.         herror(*argv);
  245.         _res.nscount = 0;
  246.         useLocalServer = TRUE;
  247.         } else {
  248. #if BSD >= 43
  249.         bcopy(hp->h_addr_list[0], &_res.nsaddr.sin_addr, hp->h_length);
  250. #else
  251.         bcopy(hp->h_addr, &_res.nsaddr.sin_addr, hp->h_length);
  252. #endif
  253.         } 
  254.     }
  255.     }
  256.  
  257.  
  258.     if (_res.nscount == 0 || useLocalServer) {
  259.     LocalServer(defaultPtr);
  260.     } else {
  261.     for (i = 0; i < _res.nscount; i++) {
  262.         if (_res.nsaddr_list[i].sin_addr.s_addr == INADDR_ANY) {
  263.             LocalServer(defaultPtr);
  264.         break;
  265.         } else {
  266.         result = FindHostInfo(&(_res.nsaddr_list[i].sin_addr), 
  267.                     &(_res.nsaddr_list[i].sin_addr), 
  268.                     sizeof(struct in_addr),
  269.                     defaultPtr);
  270.         if (result != SUCCESS) {
  271.             fprintf(stderr,
  272.             "*** Can't find server name for address %s: %s\n", 
  273.                inet_ntoa(_res.nsaddr_list[i].sin_addr), 
  274.                DecodeError(result));
  275.         } else {
  276.             defaultAddr = _res.nsaddr_list[i].sin_addr;
  277.             break;
  278.         }
  279.         }
  280.     }
  281.  
  282.     /*
  283.      *  If we have exhausted the list, tell the user about the
  284.      *  command line argument to specify an address.
  285.      */
  286.  
  287.     if (i == _res.nscount) {
  288.         fprintf(stderr, 
  289.         "*** Default servers are not available\n");
  290.         exit(1);
  291.     }
  292.  
  293.     }
  294.     strcpy(defaultServer, defaultPtr->name);
  295.     strcpy(rootServerName, ROOT_SERVER);
  296.  
  297.  
  298. #ifdef DEBUG
  299. #ifdef DEBUG2
  300.     _res.options |= RES_DEBUG2;
  301. #endif
  302.     _res.options |= RES_DEBUG;
  303.     _res.retry    = 2;
  304. #endif DEBUG
  305.  
  306.     /*
  307.      * If we're in non-interactive mode, look up the wanted host and quit.
  308.      * Otherwise, print the initial server's name and continue with
  309.      * the initialization.
  310.      */
  311.  
  312.     if (wantedHost != (char *) NULL) {
  313.     LookupHost(wantedHost, 0);
  314.     } else {
  315.     PrintHostInfo(stdout, "Default Server:", defaultPtr);
  316.  
  317.     /*
  318.      * Setup the environment to allow the interrupt handler to return here.
  319.      */
  320.  
  321.     (void) setjmp(env);
  322.  
  323.     /* 
  324.      * Return here after a longjmp.
  325.      */
  326.  
  327.     signal(SIGINT, IntrHandler);
  328.     signal(SIGPIPE, SIG_IGN);
  329.  
  330.     /*
  331.      * Read and evaluate commands. The commands are described in commands.l
  332.      * Yylex returns 0 when ^D or 'exit' is typed. 
  333.      */
  334.  
  335.     printf("> ");
  336.     while(yylex()) {
  337.         printf("> ");
  338.     }
  339.     }
  340.     exit(0);
  341. }
  342.  
  343.  
  344. LocalServer(defaultPtr)
  345.     HostInfo *defaultPtr;
  346. {
  347.     char    hostName[NAME_LEN];
  348.     int result;
  349.  
  350.     gethostname(hostName, sizeof(hostName));
  351.  
  352. #if BSD >= 43
  353.     defaultAddr.s_addr = htonl(INADDR_ANY);
  354.     (void) GetHostInfo(&defaultAddr, C_IN, T_A, "0.0.0.0", defaultPtr, 1);
  355.     free(defaultPtr->name);
  356.     defaultPtr->name = Calloc(1, sizeof(hostName)+1);
  357.     strcpy(defaultPtr->name, hostName);
  358. #else
  359.  
  360.     defaultAddr.s_addr = inet_addr(LOCALHOST);
  361.     result = GetHostInfo(&defaultAddr, C_IN, T_A, hostName, defaultPtr, 1);
  362.     if (result != SUCCESS) {
  363.     fprintf(stderr,
  364.     "*** Can't find initialize address for server %s: %s\n",
  365.             defaultServer, DecodeError(result));
  366.     exit(1);
  367.     }
  368. #endif
  369. }
  370.  
  371.  
  372. /*
  373.  *******************************************************************************
  374.  *
  375.  *  Usage --
  376.  *
  377.  *    Lists the proper methods to run the program and exits.
  378.  *
  379.  *******************************************************************************
  380.  */
  381.  
  382. Usage()
  383. {
  384.     fprintf(stderr, "Usage:\n");
  385.     fprintf(stderr,
  386. "   nslookup [-opt ...]             # interactive mode using default server\n");
  387.     fprintf(stderr,
  388. "   nslookup [-opt ...] - server    # interactive mode using 'server'\n");
  389.     fprintf(stderr,
  390. "   nslookup [-opt ...] host        # just look up 'host' using default server\n");
  391.     fprintf(stderr,
  392. "   nslookup [-opt ...] host server # just look up 'host' using 'server'\n");
  393.     exit(1);
  394. }
  395.  
  396.  
  397. /*
  398.  *******************************************************************************
  399.  *
  400.  *  SetDefaultServer --
  401.  *
  402.  *    Changes the default name server to the one specified by
  403.  *    the first argument. The command "server name" uses the current 
  404.  *    default server to lookup the info for "name". The command
  405.  *    "lserver name" uses the original server to lookup "name".
  406.  *
  407.  *  Side effects:
  408.  *    This routine will cause a core dump if the allocation requests fail.
  409.  *
  410.  *  Results:
  411.  *    SUCCESS     The default server was changed successfully.
  412.  *    NONAUTH        The server was changed but addresses of
  413.  *            other servers who know about the requested server
  414.  *            were returned.
  415.  *    Errors        No info about the new server was found or
  416.  *            requests to the current server timed-out.
  417.  *
  418.  *******************************************************************************
  419.  */
  420.  
  421. int
  422. SetDefaultServer(string, local)
  423.     char    *string;
  424.     Boolean    local;
  425. {
  426.     register HostInfo     *newDefPtr;
  427.     char         newServer[NAME_LEN];
  428.     int         result;
  429.     int         i;
  430.  
  431.     /*
  432.      *  Parse the command line. It maybe of the form "server name",
  433.      *  "lserver name" or just "name".
  434.      */
  435.  
  436.     if (local) {
  437.     i = sscanf(string, " lserver %s", newServer);
  438.     } else {
  439.     i = sscanf(string, " server %s", newServer);
  440.     }
  441.     if (i != 1) {
  442.     i = sscanf(string, " %s", newServer);
  443.     if (i != 1) {
  444.         fprintf(stderr,"SetDefaultServer: invalid name: %s\n",  string);
  445.         return(ERROR);
  446.     }
  447.     }
  448.  
  449.     /*
  450.      * Allocate space for a HostInfo variable for the new server. Don't
  451.      * overwrite the old HostInfo struct because info about the new server
  452.      * might not be found and we need to have valid default server info.
  453.      */
  454.  
  455.     newDefPtr = (HostInfo *) Calloc(1, sizeof(HostInfo));
  456.  
  457.  
  458.     /*
  459.      *    A 'local' lookup uses the original server that the program was
  460.      *  initialized with.
  461.      */
  462.  
  463.     if (local) {
  464.     result = GetHostInfo(&defaultAddr, C_IN, T_A, newServer, newDefPtr, 1);
  465.     } else {
  466.  
  467.     /*
  468.      *  Check to see if we have the address of the server or the
  469.      *    address of a server who knows about this domain.
  470.      *
  471.      *  For now, just use the first address in the list.
  472.      */
  473.     if (defaultPtr->addrList == NULL) {
  474.         result = GetHostInfo(
  475.             (struct in_addr *) defaultPtr->servers[0]->addrList[0], 
  476.                 C_IN, T_A, newServer, newDefPtr, 1);
  477.     } else {
  478.         result = GetHostInfo((struct in_addr *) defaultPtr->addrList[0], 
  479.                 C_IN, T_A, newServer, newDefPtr, 1);
  480.     }
  481.     }
  482.  
  483.     if (result == SUCCESS || result == NONAUTH) {
  484.         /*
  485.          *  Found info about the new server. Free the resources for
  486.          *  the old server.
  487.          */
  488.  
  489.         FreeHostInfoPtr(defaultPtr);
  490.         free((char *)defaultPtr);
  491.         defaultPtr = newDefPtr;
  492.         strcpy(defaultServer, defaultPtr->name);
  493.         PrintHostInfo(stdout, "Default Server:", defaultPtr);
  494.         return(SUCCESS);
  495.     } else {
  496.         fprintf(stderr, "*** Can't find address for server %s: %s\n",
  497.             newServer, DecodeError(result));
  498.         free((char *)newDefPtr);
  499.  
  500.         return(result);
  501.     }
  502. }
  503.  
  504. /*
  505.  *******************************************************************************
  506.  *
  507.  *  LookupHost --
  508.  *
  509.  *    Asks the default name server for information about the
  510.  *    specified host or domain. The information is printed
  511.  *    if the lookup was successful.
  512.  *
  513.  *  Results:
  514.  *    SUCCESS        - the lookup was successful.
  515.  *    ERROR        - the output file could not be opened.
  516.  *    Misc. Errors    - an error message is printed if the lookup failed.
  517.  *
  518.  *******************************************************************************
  519.  */
  520.  
  521. int
  522. LookupHost(string, putToFile)
  523.     char    *string;
  524.     Boolean    putToFile;
  525. {
  526.     char    host[NAME_LEN];
  527.     char    file[NAME_LEN];
  528.     int        result;
  529.  
  530.     /*
  531.      *  Invalidate the current host information to prevent Finger 
  532.      *  from using bogus info.
  533.      */
  534.  
  535.     curHostValid = FALSE;
  536.  
  537.     /*
  538.      *     Parse the command string into the host and
  539.      *     optional output file name.
  540.      *
  541.      */
  542.  
  543.     sscanf(string, " %s", host);    /* removes white space */
  544.     if (!putToFile) {
  545.     filePtr = stdout;
  546.     } else {
  547.     filePtr = OpenFile(string, file);
  548.     if (filePtr == NULL) {
  549.         fprintf(stderr, "*** Can't open %s for writing\n", file);
  550.         return(ERROR);
  551.     }
  552.     fprintf(filePtr,"> %s\n", string);
  553.     }
  554.  
  555.     PrintHostInfo(filePtr, "Server:", defaultPtr);
  556.  
  557.     /*
  558.      *  Check to see if we have the address of the server or the
  559.      *    address of a server who knows about this domain.
  560.      *
  561.      *  For now, just use the first address in the list.
  562.      */
  563.  
  564.     if (defaultPtr->addrList == NULL) {
  565.     result = GetHostInfo(
  566.             (struct in_addr *) defaultPtr->servers[0]->addrList[0], 
  567.               queryClass, queryType, host, &curHostInfo, 0);
  568.     } else {
  569.     result = GetHostInfo((struct in_addr *) defaultPtr->addrList[0], 
  570.               queryClass, queryType, host, &curHostInfo, 0);
  571.     }
  572.  
  573.     switch(result) {
  574.     case SUCCESS:
  575.         /*
  576.          *  If the query was for an address, then the curHostInfo
  577.          *  variable can be used by Finger.
  578.          *  There's no need to print anything for other query types
  579.          *  because the info has already been printed.
  580.          */
  581.         if (queryType == T_A) {
  582.         curHostValid = TRUE;
  583.         PrintHostInfo(filePtr, "Name:", &curHostInfo);
  584.         }
  585.         break;
  586.  
  587.     /*
  588.      * No Authoritative answer was available but we got names
  589.      * of servers who know about the host.
  590.      */
  591.     case NONAUTH:
  592.         PrintHostInfo(filePtr, "Name:", &curHostInfo);
  593.         break;
  594.  
  595.     case NO_INFO:
  596.         fprintf(stderr, "*** No %s information is available for %s\n", 
  597.             DecodeType(queryType), host);
  598.         break;
  599.  
  600.     case TIME_OUT:
  601.         fprintf(stderr, "*** Request to %s timed-out\n", defaultServer);
  602.         break;
  603.  
  604.     default:
  605.         fprintf(stderr, "*** %s can't find %s: %s\n", defaultServer, host,
  606.             DecodeError(result));
  607.     }
  608.     if (putToFile) {
  609.     fclose(filePtr);
  610.     filePtr = NULL;
  611.     }
  612.     return(result);
  613. }
  614.  
  615. /*
  616.  *******************************************************************************
  617.  *
  618.  *  LookupHostWithServer --
  619.  *
  620.  *    Asks the name server specified in the second argument for 
  621.  *    information about the host or domain specified in the first
  622.  *    argument. The information is printed if the lookup was successful.
  623.  *
  624.  *    Address info about the requested name server is obtained
  625.  *    from the default name server. This routine will return an
  626.  *    error if the default server doesn't have info about the 
  627.  *    requested server. Thus an error return status might not
  628.  *    mean the requested name server doesn't have info about the
  629.  *    requested host.
  630.  *
  631.  *    Comments from LookupHost apply here, too.
  632.  *
  633.  *  Results:
  634.  *    SUCCESS        - the lookup was successful.
  635.  *    ERROR        - the output file could not be opened.
  636.  *    Misc. Errors    - an error message is printed if the lookup failed.
  637.  *
  638.  *******************************************************************************
  639.  */
  640.  
  641. int
  642. LookupHostWithServer(string, putToFile)
  643.     char    *string;
  644.     Boolean    putToFile;
  645. {
  646.     char     file[NAME_LEN];
  647.     char     host[NAME_LEN];
  648.     char     server[NAME_LEN];
  649.     int     result;
  650.     static HostInfo serverInfo;
  651.  
  652.     curHostValid = FALSE;
  653.  
  654.     sscanf(string, " %s %s", host, server);
  655.     if (!putToFile) {
  656.     filePtr = stdout;
  657.     } else {
  658.     filePtr = OpenFile(string, file);
  659.     if (filePtr == NULL) {
  660.         fprintf(stderr, "*** Can't open %s for writing\n", file);
  661.         return(ERROR);
  662.     }
  663.     fprintf(filePtr,"> %s\n", string);
  664.     }
  665.     
  666.  
  667.     if (defaultPtr->addrList == NULL) {
  668.     result = GetHostInfo(
  669.             (struct in_addr *) defaultPtr->servers[0]->addrList[0], 
  670.                 C_IN, T_A, server, &serverInfo, 1);
  671.     } else {
  672.     result = GetHostInfo((struct in_addr *) defaultPtr->addrList[0], 
  673.                 C_IN, T_A, server, &serverInfo, 1);
  674.     }
  675.  
  676.     if (result != SUCCESS) {
  677.     fprintf(stderr,"*** Can't find address for server %s: %s\n", server,
  678.          DecodeError(result));
  679.     } else {
  680.     PrintHostInfo(filePtr, "Server:", &serverInfo);
  681.  
  682.     if (serverInfo.addrList == NULL) {
  683.         result = GetHostInfo(
  684.             (struct in_addr *) serverInfo.servers[0]->addrList[0], 
  685.                   queryClass, queryType, host, &curHostInfo, 0);
  686.     } else {
  687.         result = GetHostInfo((struct in_addr *) serverInfo.addrList[0], 
  688.                   queryClass, queryType, host, &curHostInfo, 0);
  689.     }
  690.  
  691.  
  692.     switch(result) {
  693.  
  694.         case SUCCESS:
  695.         if (queryType == T_A) {
  696.             curHostValid = TRUE;
  697.             PrintHostInfo(filePtr, "Name:", &curHostInfo);
  698.         }
  699.         break;
  700.  
  701.         case NONAUTH:
  702.         PrintHostInfo(filePtr, "Name:", &curHostInfo);
  703.         break;
  704.  
  705.         case NO_INFO:
  706.         fprintf(stderr, "*** No %s information is available for %s\n", 
  707.             DecodeType(queryType), host);
  708.         break;
  709.  
  710.         case TIME_OUT:
  711.         fprintf(stderr, "*** Request to %s timed-out\n", server);
  712.         break;
  713.  
  714.         default:
  715.         fprintf(stderr, "*** %s can't find %s: %s\n", server, host,
  716.             DecodeError(result));
  717.     }
  718.     }
  719.     if (putToFile) {
  720.     fclose(filePtr);
  721.     filePtr = NULL;
  722.     }
  723.     return(result);
  724. }
  725.  
  726. /*
  727.  *******************************************************************************
  728.  *
  729.  *  SetOption -- 
  730.  *
  731.  *    This routine is used to change the state information
  732.  *    that affect the lookups. The command format is
  733.  *       set keyword[=value]
  734.  *    Most keywords can be abbreviated. Parsing is very simplistic--
  735.  *    A value must not be separated from its keyword by white space.
  736.  *
  737.  *    Valid keywords:        Meaning:
  738.  *    [no]aaonly          authoritative query only or not (hidden).
  739.  *    all            lists current values of options.
  740.  *    ALL            lists current values of options, including
  741.  *                  hidden options.
  742.  *    [no]d2            turn on/off extra debugging mode (hidden).
  743.  *    [no]debug         turn on/off debugging mode.
  744.  *    [no]defname          use/don't use default domain name.
  745.  *    [no]search        use/don't use domain search list.
  746.  *    domain=NAME        set default domain name to NAME.
  747.  *    [no]ignore        ignore/don't ignore trunc. errors (hidden).
  748.  *    [no]primary         use/don't use primary server (hidden).
  749.  *    query=value        set default query type to value,
  750.  *                value is one of the query types in RFC883
  751.  *                without the leading T_.    (e.g. A, HINFO)
  752.  *    [no]recurse        use/don't use recursive lookup.
  753.  *    retry=#            set number of retries to #.
  754.  *    root=NAME        change root server to NAME.
  755.  *    time=#            set timeout length to #.
  756.  *    [no]vc            use/don't use virtual circuit.
  757.  *
  758.  *  Results:
  759.  *    SUCCESS        the command was parsed correctly.
  760.  *    ERROR        the command was not parsed correctly.
  761.  *
  762.  *******************************************************************************
  763.  */
  764.  
  765. int
  766. SetOption(option)
  767.     register char *option;
  768. {
  769.     char     type[NAME_LEN];
  770.     char     *ptr;
  771.  
  772.     while (isspace(*option))
  773.     ++option;
  774.     if (strncmp (option, "set ", 4) == 0)
  775.     option += 4;
  776.     while (isspace(*option))
  777.     ++option;
  778.  
  779.     if (*option == 0) {
  780.     fprintf(stderr, "*** Invalid set command\n");
  781.     return(ERROR);
  782.     } else {
  783.     if (strncmp(option, "all", 3) == 0) {
  784.         ShowOptions(FALSE);
  785.     } else if (strncmp(option, "ALL", 3) == 0) {
  786.         ShowOptions(TRUE);
  787.     } else if (strncmp(option, "aa", 2) == 0) {    /* aaonly */
  788.         _res.options |= RES_AAONLY;
  789.     } else if (strncmp(option, "noaa", 4) == 0) {
  790.         _res.options &= ~RES_AAONLY;
  791.     } else if (strncmp(option, "d2", 2) == 0) {    /* d2 (more debug) */
  792.         _res.options |= (RES_DEBUG | RES_DEBUG2);
  793.     } else if (strncmp(option, "nod2", 4) == 0) {
  794.         _res.options &= ~RES_DEBUG2;
  795.     } else if (strncmp(option, "def", 3) == 0) {    /* defname */
  796.         _res.options |= RES_DEFNAMES;
  797.     } else if (strncmp(option, "nodef", 5) == 0) {
  798.         _res.options &= ~RES_DEFNAMES;
  799.     } else if (strncmp(option, "do", 2) == 0) {    /* domain */
  800.         ptr = index(option, '=');
  801.         if (ptr != NULL) {
  802.         sscanf(++ptr, "%s", _res.defdname);
  803.         res_re_init();
  804.         }
  805.     } else if (strncmp(option, "deb", 1) == 0) {    /* debug */
  806.         _res.options |= RES_DEBUG;
  807.     } else if (strncmp(option, "nodeb", 3) == 0) {
  808.         _res.options &= ~(RES_DEBUG | RES_DEBUG2);
  809.     } else if (strncmp(option, "i", 1) == 0) {    /* ignore */
  810.         _res.options |= RES_IGNTC;
  811.     } else if (strncmp(option, "noi", 3) == 0) {
  812.         _res.options &= ~RES_IGNTC;
  813.     } else if (strncmp(option, "p", 1) == 0) {    /* primary */
  814.         _res.options |= RES_PRIMARY;
  815.     } else if (strncmp(option, "nop", 3) == 0) {
  816.         _res.options &= ~RES_PRIMARY;
  817.     } else if (strncmp(option, "q", 1) == 0 ||    /* querytype */
  818.       strncmp(option, "ty", 2) == 0) {
  819.         ptr = index(option, '=');
  820.         if (ptr != NULL) {
  821.         sscanf(++ptr, "%s", type);
  822.         queryType = StringToType(type, queryType);
  823.         }
  824.     } else if (strncmp(option, "cl", 2) == 0) {    /* query class */
  825.         ptr = index(option, '=');
  826.         if (ptr != NULL) {
  827.         sscanf(++ptr, "%s", type);
  828.         queryClass = StringToClass(type, queryClass);
  829.         }
  830.     } else if (strncmp(option, "rec", 3) == 0) {    /* recurse */
  831.         _res.options |= RES_RECURSE;
  832.     } else if (strncmp(option, "norec", 5) == 0) {
  833.         _res.options &= ~RES_RECURSE;
  834.     } else if (strncmp(option, "ret", 3) == 0) {    /* retry */
  835.         ptr = index(option, '=');
  836.         if (ptr != NULL) {
  837.         sscanf(++ptr, "%d", &_res.retry);
  838.         }
  839.     } else if (strncmp(option, "ro", 2) == 0) {    /* root */
  840.         ptr = index(option, '=');
  841.         if (ptr != NULL) {
  842.         sscanf(++ptr, "%s", rootServerName);
  843.         }
  844.     } else if (strncmp(option, "sea", 3) == 0) {    /* search list */
  845.         _res.options |= RES_DNSRCH;
  846.     } else if (strncmp(option, "nosea", 5) == 0) {
  847.         _res.options &= ~RES_DNSRCH;
  848.     } else if (strncmp(option, "t", 1) == 0) {    /* timeout */
  849.         ptr = index(option, '=');
  850.         if (ptr != NULL) {
  851.         sscanf(++ptr, "%d", &_res.retrans);
  852.         }
  853.     } else if (strncmp(option, "v", 1) == 0) {    /* vc */
  854.         _res.options |= RES_USEVC;
  855.     } else if (strncmp(option, "nov", 3) == 0) {
  856.         _res.options &= ~RES_USEVC;
  857.     } else {
  858.         fprintf(stderr, "*** Invalid option: %s\n",  option);
  859.         return(ERROR);
  860.     }
  861.     }
  862.     return(SUCCESS);
  863. }
  864.  
  865. /*
  866.  * Fake a reinitialization when the domain is changed.
  867.  */
  868. res_re_init()
  869. {
  870.     register char *cp, **pp;
  871.     int n;
  872.  
  873.     /* find components of local domain that might be searched */
  874.     pp = _res.dnsrch;
  875.     *pp++ = _res.defdname;
  876.     for (cp = _res.defdname, n = 0; *cp; cp++)
  877.     if (*cp == '.')
  878.         n++;
  879.     cp = _res.defdname;
  880.     for (; n >= LOCALDOMAINPARTS && pp < _res.dnsrch + MAXDNSRCH; n--) {
  881.     cp = index(cp, '.');
  882.     *pp++ = ++cp;
  883.     }
  884.     *pp = 0;
  885.     _res.options |= RES_INIT;
  886. }
  887.  
  888. /*
  889.  *******************************************************************************
  890.  *
  891.  *  ShowOptions --
  892.  *
  893.  *    Prints out the state information used by the resolver
  894.  *    library and other options set by the user.
  895.  *
  896.  *******************************************************************************
  897.  */
  898.  
  899. void
  900. ShowOptions(special)
  901.     int special;
  902. {
  903.     int i;
  904.     register char **cp;
  905.  
  906.     PrintHostInfo(stdout, "Default Server:", defaultPtr);
  907.     if (curHostValid) {
  908.     PrintHostInfo(stdout, "Host:", &curHostInfo);
  909.     }
  910.  
  911.     printf("Set options:\n");
  912.     printf("  %sdebug  \t", (_res.options & RES_DEBUG) ? "" : "no");
  913.     printf("  %sdefname\t", (_res.options & RES_DEFNAMES) ? "" : "no");
  914.     printf("  %ssearch\t", (_res.options & RES_DNSRCH) ? "" : "no");
  915.     printf("  %srecurse\t", (_res.options & RES_RECURSE) ? "" : "no");
  916.     printf("  %svc\n", (_res.options & RES_USEVC) ? "" : "no");
  917.  
  918.     if (special) {
  919.     printf("  %saa\t\t", (_res.options & RES_AAONLY) ? "" : "no");
  920.     printf("  %sd2\t\t", (_res.options & RES_DEBUG2) ? "" : "no");
  921.     printf("  %signoretc\t", (_res.options & RES_IGNTC) ? "" : "no");
  922.     printf("  %sprimary\n", (_res.options & RES_PRIMARY) ? "" : "no");
  923.     }
  924.  
  925.     printf("  querytype=%s\t", p_type(queryType));
  926.     printf("  class=%s\t", p_class(queryClass));
  927.     printf("  timeout=%d\t", _res.retrans);
  928.     printf("  retry=%d\n", _res.retry);
  929.     printf("  domain=%s\n", _res.defdname);
  930.     printf("  search list: ");
  931.     for (cp = _res.dnsrch; *cp; cp++)
  932.     printf("%s ", *cp);
  933.     printf("\n  root=%s\n", rootServerName);
  934.  
  935.     if (special) {
  936.     printf("\n");
  937.     printf("State info:\n");
  938.     printf("  current packet id:       %d\n", (int)_res.id);
  939.     printf("  number of name servers:  %d\n", _res.nscount);
  940.     printf("  name server addresses:   %s\n",
  941.                     inet_ntoa(_res.nsaddr_list[0].sin_addr));
  942.     for (i = 1; i < _res.nscount; i++) {
  943.         printf("                           %s\n", 
  944.             inet_ntoa(_res.nsaddr_list[i].sin_addr));
  945.     }
  946.     }
  947. }
  948.  
  949. /*
  950.  *******************************************************************************
  951.  *
  952.  *  PrintHelp --
  953.  *
  954.  *    Prints out the help file.
  955. *    (Code taken from Mail.)
  956.  *
  957.  *******************************************************************************
  958.  */
  959.  
  960. void
  961. PrintHelp()
  962. {
  963.     register int c;
  964.     register FILE *helpFilePtr;
  965.  
  966.     if ((helpFilePtr = fopen(HELPFILE, "r")) == NULL) {
  967.         perror(HELPFILE);
  968.         return;
  969.     } 
  970.     while ((c = getc(helpFilePtr)) != EOF) {
  971.         putchar((char) c);
  972.     }
  973.     fclose(helpFilePtr);
  974. }
  975. @
  976.  
  977.  
  978. 1.1
  979. log
  980. @Initial revision
  981. @
  982. text
  983. @d319 1
  984. @
  985.